///安装webAssembly：cargo install wasm-pack 运行：wasm-pack build --target web
/// let path = PathBuf::from("example.txt"); // 从文件名创建一个PathBuf
///     let current_directory = env::current_dir().unwrap(); // 获取当前工作目录
///     let full_path = current_directory.join(path); // 将PathBuf附加到当前工作目录，形成完整路径
///     let relative_path = full_path.strip_prefix(&current_directory).unwrap(); // 通过strip_prefix函数来获取相对路径
///     println!("{:?}", relative_path); // 打印相对路径
use std::io::prelude::*;
use std::net::{
    TcpStream,
    TcpListener,
};
use std::{
    fs,
    thread ,
};


use std::env;

fn main() {
    println!("127.0.0.1:7878");
    //监听 TCP 连接
    let listener = TcpListener::bind("127.0.0.1:7878").unwrap();

    let pool = ThreadPool::new(4);

    for stream in listener.incoming() {
        let stream = stream.unwrap();


        thread::spawn(|| {
            handle_connection(stream);
        });
    }
    //读取请求
    fn handle_connection(mut stream: TcpStream) {
        let mut buffer = [0; 1024];

        stream.read(&mut buffer).unwrap();
        let get = b"GET / HTTP/1.1\r\n";

        let current_directory = env::current_dir().unwrap(); // 获取当前工作目录
        let mut webpath;



        let (status_line, filename) = if buffer.starts_with(get) {
            webpath  = format!("{}/index.html", current_directory.display());
            ("HTTP/1.1 200 OK", webpath)
        } else {
            webpath  = format!("{}/index.html", current_directory.display());
            ("HTTP/1.1 404 NOT FOUND", webpath)
        };

        let contents = fs::read_to_string(filename).unwrap();

        let response = format!(
            "{}\r\nContent-Length: {} \r\n\r\n{}",
            status_line,
            contents.len(),
            contents
        );

        stream.write(response.as_bytes()).unwrap();
        stream.flush().unwrap();
        println!("{}",stream.peer_addr().unwrap());

        println!("Request: {}", String::from_utf8_lossy(&buffer[..]));
    }
}


use std::sync::mpsc;
use std::sync::Arc;
use std::sync::Mutex;
pub struct ThreadPool{
    workers: Vec<Worker>,
    sender: mpsc::Sender<Job>,
}

type Job = Box<dyn FnOnce() + Send + 'static>;
impl ThreadPool {

    pub fn new(size: usize) -> ThreadPool {
        assert!(size > 0);

        let (sender, receiver) = mpsc::channel();

        let receiver = Arc::new(Mutex::new(receiver));

        let mut workers = Vec::with_capacity(size);

        for id in 0..size {
            workers.push(Worker::new(id, Arc::clone(&receiver)));
        }

        ThreadPool {
            workers,
            sender,
        }
    }
    pub fn execute<F>(&self, f: F)
        where
            F: FnOnce() + Send + 'static
    {
        let job = Box::new(f);

        self.sender.send(job).unwrap();
    }
}
struct Worker {
    id: usize,
    thread: thread::JoinHandle<()>,
}

impl Worker {
    fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
        let thread = thread::spawn(move || {
            loop {
                let job = receiver.lock().unwrap().recv().unwrap();

                println!("Worker {} got a job; executing.", id);

                job();
            }
        });
        Worker {
            id,
            thread,
        }
    }
}